/**
 *
 */
package com.vic.kjlink.simpletools.attachment.socket;

import com.vic.kjlink.simpletools.attachment.constant.AttachmentConstant;
import com.vic.kjlink.simpletools.attachment.model.Attachment;
import com.vic.kjlink.simpletools.attachment.model.HandleResult;
import com.vic.kjlink.simpletools.attachment.service.AttachmentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import pers.vic.boot.base.vo.BooleanWithMsg;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 日志实时通信
 *
 * @author Vic.xu
 */
@ServerEndpoint(value = AttachmentConstant.SOCKET_URL)
@Component
public class AttachmentSocket {

    /** 记录当前在线连接数 */
    public static AtomicInteger onlineCount = new AtomicInteger(0);

    private static String END_FLAG = "[END]";

    private static Logger logger = LoggerFactory.getLogger(AttachmentSocket.class);

    /**
     * 因为Socket是多例
     */
    private static AttachmentService attachmentService;

    @Autowired
    public void setAttachmentService(AttachmentService attachmentService) {
        if (AttachmentSocket.attachmentService == null) {
            AttachmentSocket.attachmentService = attachmentService;
        }
    }

    /**
     * 关闭session的时候删除记录的对应信息
     * @param session
     */
    private static void removeSession(Session session) {
        String id = session.getId();

    }


    /**
     * 服务端发送消息给客户端
     */
    private static boolean sendMessage(String message, Session toSession) {
        if (!toSession.isOpen()) {
            return false;
        }
        if (!END_FLAG.equals(message)) {
            message = message + "<br />";
        }
        try {
            toSession.getBasicRemote().sendText(message);
            return true;
        } catch (Exception e) {
            logger.error("服务端发送消息给客户端失败：{}", e);
        }
        return false;
    }


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        onlineCount.incrementAndGet(); // 在线数加1
        logger.info("有新连接加入：{}，当前总数为：{}", session.getId(), onlineCount.get());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        onlineCount.decrementAndGet(); // 在线数减1
        logger.info("有一连接关闭：{}，当前总数为：{}", session.getId(), onlineCount.get());
        // 删除连接
        removeSession(session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息：  这里只会发送 （sql==文件夹名)
     *
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
        if (StringUtils.hasText(message) && message.split("==").length == 2) {
            String s = String.join(" ", message.split("=="));
            handle(message.split("==")[0], message.split("==")[1], session);
        } else {
            sendMessage("请输入正确是数据", session);
        }
    }


    public void handle(String sql, String target, Session session) {
        try {
            //清空目标文件夹
            File file = new File(target);
            if (file.exists()) {
                file.delete();
            }
            file.mkdirs();
            List<Attachment> list = attachmentService.list(sql);
            if (CollectionUtils.isEmpty(list)) {
                sendMessage("没有需要处理的附件", session);
                return;
            }
            HandleResult handleResult = new HandleResult(list);

            Random r = new Random();
            for (Attachment attachment : list) {
                BooleanWithMsg result = attachmentService.copy(attachment, target, handleResult);
                sendMessage(result.getMessage(), session);
            }
            sendMessage(" ", session);
            sendMessage(handleResult.getDesc(), session);
        } catch (Exception ex) {
            ex.printStackTrace();
            sendMessage("出错了：" + ex.getMessage(), session);
        } finally {
            sendMessage(END_FLAG, session);
        }

    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("发生错误");
        error.printStackTrace();
    }

}
